// Dart imports:
import 'dart:convert';
import 'dart:developer';

// Flutter imports:
import 'package:amazcart/AppConfig/api_keys.dart';
import 'package:amazcart/controller/address_book_controller.dart';
import 'package:amazcart/controller/settings_controller.dart';
import 'package:amazcart/utils/styles.dart';
import 'package:amazcart/widgets/amazcart_widget/AppBarWidget.dart';
import 'package:amazcart/widgets/amazcart_widget/snackbars.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_stripe/flutter_stripe.dart';

import 'package:get/get.dart';
import 'package:http/http.dart' as http;
// import 'package:stripe_sdk/stripe_sdk.dart';
// import 'package:stripe_sdk/stripe_sdk_ui.dart';

// Project imports:

class MyStripePayment {
  Map<String, dynamic>? paymentIntent;

  Future<String> displayPaymentSheet({required String paymentId}) async {
    try {
      String pId = await Stripe.instance.presentPaymentSheet().then((value) {
        return paymentId;
      }).onError((error, stackTrace) {
        print('Error is:--->$error $stackTrace');
        return '';
      });
      return pId;
    } on StripeException catch (e) {
      print('Error is:---> $e');
      showDialog(
        context: Get.context!,
        builder: (_) => AlertDialog(
          content: Text("Cancelled".tr),
        ),
      );
      return '';
    } catch (e) {
      print('$e');
      return '';
    }
  }

  Future<String> makePayment({
    required int amount,
  }) async {
    try {
      paymentIntent = await createPaymentIntent(amount: amount);

      print('payment intent----------->');
      print(paymentIntent);

      var gpay = const PaymentSheetGooglePay(
        merchantCountryCode: "US",
        currencyCode: "USD",
        testEnv: true,
      );
      await Stripe.instance.initPaymentSheet(
        paymentSheetParameters: SetupPaymentSheetParameters(
          paymentIntentClientSecret: paymentIntent?["client_secret"] ?? '',
          style: ThemeMode.light,
          merchantDisplayName: "amazcart",
          googlePay: gpay,
        ),
      );

      String result = await displayPaymentSheet(
        paymentId: paymentIntent?["id"] ?? '',
      );
      print('result issss:::: makePayment $result');
      return result;
    } catch (e) {
      print(e.toString());
      return '';
    }
  }

  Future<Map<String, dynamic>?> createPaymentIntent({
    required int amount,
  }) async {
    try {
      GeneralSettingsController currencyController =
      Get.put(GeneralSettingsController());

      Map<String, dynamic> body = {
        "amount": "$amount",
        "currency": "${currencyController.currencyCode.value.toLowerCase()}",
      };

      http.Response response = await http.post(
          Uri.parse("https://api.stripe.com/v1/payment_intents"),
          body: body,
          headers: {
            "Authorization": "Bearer $stripeSecrateKey",
            "Content-Type": "application/x-www-form-urlencoded",
          });
      return json.decode(response.body);
    } catch (e) {
      throw Exception(e.toString());
    }
  }
}

class StripePaymentScreen extends StatefulWidget {
  final Map? orderData;
  final Map? paymentData;
  final Function(Map)? onFinish;

  StripePaymentScreen({
    this.orderData,
    this.paymentData,
    this.onFinish,
  });

  @override
  _StripePaymentScreenState createState() => _StripePaymentScreenState();
}

class _StripePaymentScreenState extends State<StripePaymentScreen> {
  final AddressController addressController = Get.put(AddressController());
  final GeneralSettingsController currencyController =
      Get.put(GeneralSettingsController());

  final String postCreateIntentURL = "$stripeServerURL/payment-intent";

  final GlobalKey<FormState> formKey = GlobalKey<FormState>();
  // final StripeCard card = StripeCard();
  //
  // final Stripe stripe = Stripe(
  //   "$stripePublishableKey", //Your Publishable Key
  //   // returnUrlForSca: "stripesdk://3ds.stripesdk.io", //Return URL for SCA
  // );

  GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();
  bool paymentLoading = false;

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        resizeToAvoidBottomInset: false,
        key: _scaffoldKey,
        backgroundColor: AppStyles.appBackgroundColor,
        appBar: AppBarWidget(
          title: 'Stripe Payment'.tr,
        ),
        body: Opacity(
          opacity: paymentLoading ? 0.3 : 1.0,
          child: SingleChildScrollView(
            child: GestureDetector(
              onTap: () {
                FocusScope.of(context).requestFocus(new FocusNode());
              },
              child: Column(
                children: [
                  // CardForm(
                  //   formKey: formKey,
                  //   card: card,
                  //   displayAnimatedCard: true,
                  // ),
                  paymentLoading
                      ? Center(
                          child: CircularProgressIndicator(
                            color: Colors.deepPurpleAccent,
                          ),
                        )
                      : Container(
                          child: ElevatedButton(
                              child: Container(
                                width: MediaQuery.of(context).size.width * 0.3,
                                alignment: Alignment.center,
                                height: 40.h,
                                child: Text(
                                  'Continue'.tr,
                                  textAlign: TextAlign.center,
                                  style: Get.textTheme.titleSmall
                                      ?.copyWith(color: Colors.white),
                                ),
                              ),
                              onPressed: () {
                                formKey.currentState?.validate();
                                formKey.currentState?.save();
                                // buy(context);
                              }),
                        ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }

  // void buy(context) async {
  //   final StripeCard stripeCard = card;
  //   final String customerEmail =
  //       addressController.shippingAddress.value.email ?? '';
  //
  //   if (!stripeCard.validateCVC()) {
  //     showAlertDialog(context, "Error", "CVC not valid.");
  //     return;
  //   }
  //   if (!stripeCard.validateDate()) {
  //     showAlertDialog(context, "Errore", "Date not valid.");
  //     return;
  //   }
  //   if (!stripeCard.validateNumber()) {
  //     showAlertDialog(context, "Error", "Number not valid.");
  //     return;
  //   }
  //
  //   setState(() {
  //     paymentLoading = true;
  //   });
  //
  //   Map<String, dynamic>? paymentIntentRes = await createPaymentIntent(
  //     stripeCard: stripeCard,
  //     customerEmail: customerEmail,
  //   );
  //   print('Payment Intent response => $paymentIntentRes');
  //   print("---" * 10);
  //   String clientSecret = paymentIntentRes?['client_secret'];
  //   String paymentMethodId = paymentIntentRes?['payment_method'];
  //   String status = paymentIntentRes?['status'];
  //
  //   print("Status is => $status");
  //   if (status == 'requires_action' || status == 'requires_confirmation') {
  //     paymentIntentRes =
  //         await confirmPayment3DSecure(clientSecret, paymentMethodId);
  //     print("Stauts after confirmation => ${paymentIntentRes?['status']}");
  //     if (paymentIntentRes?['status'] == 'succeeded') {
  //       SnackBars().snackBarSuccessBottom("Success! Thanks for buying.");
  //       Future.delayed(Duration(seconds: 4), () {
  //         setState(() {
  //           paymentLoading = false;
  //         });
  //         Map data = {
  //           'id': paymentIntentRes?['id'],
  //           'status': paymentIntentRes?['status'],
  //         };
  //         widget.onFinish!(data);
  //         Navigator.of(context).pop();
  //       });
  //     } else {
  //       setState(() {
  //         paymentLoading = false;
  //       });
  //       showAlertDialog(
  //           context, "Error", "Payment failed. ${paymentIntentRes?['status']}");
  //     }
  //   } else if (status != 'succeeded') {
  //     SnackBars().snackBarWarning("Warning! Canceled Transaction.");
  //     Future.delayed(Duration(seconds: 4), () {
  //       setState(() {
  //         paymentLoading = false;
  //       });
  //     });
  //   } else if (status == 'succeeded') {
  //     SnackBars().snackBarSuccessBottom("Success! Thanks for buying.");
  //     Future.delayed(Duration(seconds: 4), () {
  //       setState(() {
  //         paymentLoading = false;
  //       });
  //       Map data = {
  //         'id': paymentIntentRes?['id'],
  //         'status': paymentIntentRes?['status'],
  //       };
  //       widget.onFinish!(data);
  //       Navigator.of(context).pop();
  //     });
  //   } else {
  //     SnackBars().snackBarWarning(
  //         "Warning! Transaction rejected.\nSomething went wrong");
  //     Future.delayed(Duration(seconds: 4), () {
  //       setState(() {
  //         paymentLoading = false;
  //       });
  //     });
  //   }
  // }

  // Future<Map<String, dynamic>?> createPaymentIntent({
  //   required StripeCard stripeCard,
  //   required String customerEmail,
  // }) async {
  //   stripeCard.postalCode='6700';
  //   stripeCard.last4='4242';
  //   print('stripe info is::::: Email: $customerEmail');
  //   print('cvc: ${stripeCard.cvc}');
  //   print('expMonth: ${stripeCard.expMonth}');
  //   print('expYear: ${stripeCard.expYear}');
  //   print('last4: ${stripeCard.last4}');
  //   print('number: ${stripeCard.number}');
  //   print('postalCode: ${stripeCard.postalCode}');
  //   String? clientSecret;
  //   Map<String, dynamic>? paymentIntentRes, paymentMethod;
  //   try {
  //     paymentMethod = await stripe.api.createPaymentMethodFromCard(stripeCard);
  //     clientSecret = await postCreatePaymentIntent(
  //       email: customerEmail,
  //       paymentMethodId: paymentMethod['id'],
  //     );
  //     paymentIntentRes =
  //         await stripe.api.retrievePaymentIntent(clientSecret ?? '');
  //   } catch (e) {
  //     print("ERROR_CreatePaymentIntentAndSubmit: $e");
  //     showAlertDialog(context, "Error", "Something went wrong.");
  //   }
  //   return paymentIntentRes;
  // }

  Future<String?> postCreatePaymentIntent({
    required String email,
    required String paymentMethodId,
  }) async {
    final amount =
        (double.parse(widget.orderData?['grand_total'].toString() ?? '') * 100)
            .toInt();
    print("AMOUNT => $amount");
    final url = Uri.parse(postCreateIntentURL +
        "?amount=$amount&payment_method_id=$paymentMethodId&email=$email&currency=${currencyController.currencyCode.value.toLowerCase()}");
    print("URL is $url");
    http.Response response = await http.post(
      url,
      headers: {'Content-Type': 'application/json'},
    );
    print('response status code => ${response.statusCode}');
    log('${response.body}');
    print("---" * 12);
    final stripeIntentResponse = stripeIntentResponseFromJson(response.body);
    return stripeIntentResponse.paymentIntent?.clientSecret;
  }

  // Future<Map<String, dynamic>?> confirmPayment3DSecure(
  //     String clientSecret, String paymentMethodId) async {
  //   Map<String, dynamic>? paymentIntentRes_3dSecure;
  //   try {
  //     await stripe.confirmPayment(clientSecret, context,
  //         paymentMethodId: paymentMethodId);
  //     paymentIntentRes_3dSecure =
  //         await stripe.api.retrievePaymentIntent(clientSecret);
  //   } catch (e) {
  //     print("ERROR_ConfirmPayment3DSecure: $e");
  //     showAlertDialog(context, "Error", "$e");
  //   }
  //   return paymentIntentRes_3dSecure;
  // }

  String getCustomerEmail() {
    String customerEmail;
    //Define how to get this info.
    // -Ask to the customer through a textfield.
    // -Get it from firebase Account.
    customerEmail = "alessandro.berti@me.it";
    return customerEmail;
  }

  showAlertDialog(BuildContext context, String title, String message) {
    setState(() {
      paymentLoading = false;
    });
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text(title,style: AppStyles.kFontBlack13w4,),
          content: Text(message,style: AppStyles.kFontBlack12w4),
          actions: [
            TextButton(
              child: Text("OK".tr,style: AppStyles.kFontBlack13w4),
              onPressed: () {
                Navigator.of(context).pop();
              }, // dismiss dialog
            ),
          ],
        );
      },
    );
  }
}

// To parse this JSON data, do
//
//     final stripeIntentResponse = stripeIntentResponseFromJson(jsonString);

StripeIntentResponse stripeIntentResponseFromJson(String str) =>
    StripeIntentResponse.fromJson(json.decode(str));

String stripeIntentResponseToJson(StripeIntentResponse data) =>
    json.encode(data.toJson());

class StripeIntentResponse {
  StripeIntentResponse({
    this.paymentIntent,
  });

  PaymentIntent? paymentIntent;

  factory StripeIntentResponse.fromJson(Map<String, dynamic> json) =>
      StripeIntentResponse(
        paymentIntent: PaymentIntent.fromJson(json["paymentIntent"]),
      );

  Map<String, dynamic> toJson() => {
        "paymentIntent": paymentIntent?.toJson(),
      };
}

class PaymentIntent {
  PaymentIntent({
    this.id,
    this.object,
    this.amount,
    this.amountCapturable,
    this.amountReceived,
    this.application,
    this.applicationFeeAmount,
    this.canceledAt,
    this.cancellationReason,
    this.captureMethod,
    this.charges,
    this.clientSecret,
    this.confirmationMethod,
    this.created,
    this.currency,
    this.customer,
    this.description,
    this.invoice,
    this.lastPaymentError,
    this.livemode,
    this.metadata,
    this.nextAction,
    this.onBehalfOf,
    this.paymentMethod,
    this.paymentMethodOptions,
    this.paymentMethodTypes,
    this.receiptEmail,
    this.review,
    this.setupFutureUsage,
    this.shipping,
    this.source,
    this.statementDescriptor,
    this.statementDescriptorSuffix,
    this.status,
    this.transferData,
    this.transferGroup,
  });

  String? id;
  String? object;
  int? amount;
  int? amountCapturable;
  int? amountReceived;
  dynamic application;
  dynamic applicationFeeAmount;
  dynamic canceledAt;
  dynamic cancellationReason;
  String? captureMethod;
  Charges? charges;
  String? clientSecret;
  String? confirmationMethod;
  int? created;
  String? currency;
  dynamic customer;
  dynamic description;
  dynamic invoice;
  dynamic lastPaymentError;
  bool? livemode;
  Metadata? metadata;
  dynamic nextAction;
  dynamic onBehalfOf;
  String? paymentMethod;
  PaymentMethodOptions? paymentMethodOptions;
  List<String>? paymentMethodTypes;
  String? receiptEmail;
  dynamic review;
  dynamic setupFutureUsage;
  dynamic shipping;
  dynamic source;
  dynamic statementDescriptor;
  dynamic statementDescriptorSuffix;
  String? status;
  dynamic transferData;
  dynamic transferGroup;

  factory PaymentIntent.fromJson(Map<String, dynamic> json) => PaymentIntent(
        id: json["id"],
        object: json["object"],
        amount: json["amount"],
        amountCapturable: json["amount_capturable"],
        amountReceived: json["amount_received"],
        application: json["application"],
        applicationFeeAmount: json["application_fee_amount"],
        canceledAt: json["canceled_at"],
        cancellationReason: json["cancellation_reason"],
        captureMethod: json["capture_method"],
        charges: Charges.fromJson(json["charges"]),
        clientSecret: json["client_secret"],
        confirmationMethod: json["confirmation_method"],
        created: json["created"],
        currency: json["currency"],
        customer: json["customer"],
        description: json["description"],
        invoice: json["invoice"],
        lastPaymentError: json["last_payment_error"],
        livemode: json["livemode"],
        metadata: Metadata.fromJson(json["metadata"]),
        nextAction: json["next_action"],
        onBehalfOf: json["on_behalf_of"],
        paymentMethod: json["payment_method"],
        paymentMethodOptions:
            PaymentMethodOptions.fromJson(json["payment_method_options"]),
        paymentMethodTypes:
            List<String>.from(json["payment_method_types"].map((x) => x)),
        receiptEmail: json["receipt_email"],
        review: json["review"],
        setupFutureUsage: json["setup_future_usage"],
        shipping: json["shipping"],
        source: json["source"],
        statementDescriptor: json["statement_descriptor"],
        statementDescriptorSuffix: json["statement_descriptor_suffix"],
        status: json["status"],
        transferData: json["transfer_data"],
        transferGroup: json["transfer_group"],
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "object": object,
        "amount": amount,
        "amount_capturable": amountCapturable,
        "amount_received": amountReceived,
        "application": application,
        "application_fee_amount": applicationFeeAmount,
        "canceled_at": canceledAt,
        "cancellation_reason": cancellationReason,
        "capture_method": captureMethod,
        "charges": charges?.toJson(),
        "client_secret": clientSecret,
        "confirmation_method": confirmationMethod,
        "created": created,
        "currency": currency,
        "customer": customer,
        "description": description,
        "invoice": invoice,
        "last_payment_error": lastPaymentError,
        "livemode": livemode,
        "metadata": metadata?.toJson(),
        "next_action": nextAction,
        "on_behalf_of": onBehalfOf,
        "payment_method": paymentMethod,
        "payment_method_options": paymentMethodOptions?.toJson(),
        "payment_method_types":
            List<dynamic>.from(paymentMethodTypes?.map((x) => x) ?? []),
        "receipt_email": receiptEmail,
        "review": review,
        "setup_future_usage": setupFutureUsage,
        "shipping": shipping,
        "source": source,
        "statement_descriptor": statementDescriptor,
        "statement_descriptor_suffix": statementDescriptorSuffix,
        "status": status,
        "transfer_data": transferData,
        "transfer_group": transferGroup,
      };
}

class Charges {
  Charges({
    this.object,
    this.data,
    this.hasMore,
    this.totalCount,
    this.url,
  });

  String? object;
  List<dynamic>? data;
  bool? hasMore;
  int? totalCount;
  String? url;

  factory Charges.fromJson(Map<String, dynamic> json) => Charges(
        object: json["object"],
        data: List<dynamic>.from(json["data"].map((x) => x)),
        hasMore: json["has_more"],
        totalCount: json["total_count"],
        url: json["url"],
      );

  Map<String, dynamic> toJson() => {
        "object": object,
        "data": List<dynamic>.from(data?.map((x) => x) ?? []),
        "has_more": hasMore,
        "total_count": totalCount,
        "url": url,
      };
}

class Metadata {
  Metadata();

  factory Metadata.fromJson(Map<String, dynamic> json) => Metadata();

  Map<String, dynamic> toJson() => {};
}

class PaymentMethodOptions {
  PaymentMethodOptions({
    this.card,
  });

  Card? card;

  factory PaymentMethodOptions.fromJson(Map<String, dynamic> json) =>
      PaymentMethodOptions(
        card: Card.fromJson(json["card"]),
      );

  Map<String, dynamic> toJson() => {
        "card": card?.toJson(),
      };
}

class Card {
  Card({
    this.installments,
    this.network,
    this.requestThreeDSecure,
  });

  dynamic installments;
  dynamic network;
  String? requestThreeDSecure;

  factory Card.fromJson(Map<String, dynamic> json) => Card(
        installments: json["installments"],
        network: json["network"],
        requestThreeDSecure: json["request_three_d_secure"],
      );

  Map<String, dynamic> toJson() => {
        "installments": installments,
        "network": network,
        "request_three_d_secure": requestThreeDSecure,
      };
}
